#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
TrustedImageFile parser
"""

import os
import logging
from enum import Enum, auto

logger = logging.getLogger(__name__)

class CommandType(Enum):
    """Define supported command types"""
    FROM = auto()
    INSTALL = auto()
    COPY = auto()
    RUN = auto()
    SET_KERNEL_CMDLINE = auto()
    SET_ROOTPASSWD = auto()
    SSH_INJECT = auto()
    SELINUX_RELABEL = auto()
    DM_VERITY = auto()
    OUTPUT = auto()
    
    @classmethod
    def from_string(cls, cmd_string):
        """Convert from string to enum value"""
        try:
            return cls[cmd_string.upper()]
        except KeyError:
            raise ValueError(f"Unsupported command: {cmd_string}")

class Command:
    """表示配置文件中的一条命令"""
    def __init__(self, cmd_type, args):
        self.type = cmd_type
        self.args = args
    
    def __str__(self):
        return f"{self.type.name}: {' '.join(self.args)}"

class TrustedImageParser:
    """TrustedImageFile parser"""
    
    def __init__(self, file_path):
        self.file_path = file_path
        self.commands = []
        self.base_image = None
        self.output_format = None
        self.output_name = None
    
    def parse(self):
        """Parse config file"""
        if not os.path.isfile(self.file_path):
            raise FileNotFoundError(f"Config file does not exist: {self.file_path}")
        
        logger.info(f"Start parsing config file: {self.file_path}")
        
        with open(self.file_path, 'r', encoding='utf-8') as f:
            line_number = 0
            for line in f:
                line_number += 1
                line = line.strip()
                
                # 跳过空行和注释
                if not line or line.startswith('#'):
                    continue
                
                # 分割命令和参数
                parts = line.split(maxsplit=1)
                if not parts:
                    continue
                
                cmd_string = parts[0].strip()
                args = []
                if len(parts) > 1:
                    args = parts[1].strip().split()
                
                try:
                    # Handle special commands
                    if cmd_string.upper() == 'FROM':
                        if not args:
                            raise ValueError("FROM command requires a base image")
                        self.base_image = args[0]
                        logger.debug(f"Set base image: {self.base_image}")
                    elif cmd_string.upper() == 'OUTPUT':
                        if len(args) < 2:
                            raise ValueError("OUTPUT command requires format and output name")
                        self.output_format = args[0]
                        self.output_name = args[1]
                        logger.debug(f"Set output format: {self.output_format}, name: {self.output_name}")
                    
                    # Create command object
                    cmd_type = CommandType.from_string(cmd_string)
                    command = Command(cmd_type, args)
                    self.commands.append(command)
                    logger.debug(f"Parsed command: {command}")
                    
                except ValueError as e:
                    logger.warning(f"Parse error at line {line_number}: {e}")
        
        if not self.base_image:
            raise ValueError("Config file must contain FROM command to specify base image")
        
        logger.info(f"Parsing complete, total {len(self.commands)} commands")
        return self.commands
    
    def get_base_image(self):
        """Get base image"""
        return self.base_image
    
    def get_output_info(self):
        """Get output info"""
        return self.output_format, self.output_name 